xlat: Set AP[1] to 1 when it is RES1
authorAntonio Nino Diaz <[email protected]>
Thu, 26 Apr 2018 11:59:08 +0000 (12:59 +0100)
committerAntonio Nino Diaz <[email protected]>
Thu, 26 Apr 2018 11:59:08 +0000 (12:59 +0100)
According to the ARMv8 ARM issue C.a:

    AP[1] is valid only for stage 1 of a translation regime that can
    support two VA ranges. It is RES 1 when stage 1 translations can
    support only one VA range.

This means that, even though this bit is ignored, it should be set to 1
in the EL3 and EL2 translation regimes.

For translation regimes consisting on EL0 and a higher regime this bit
selects between control at EL0 or at the higher Exception level. The
regimes that support two VA ranges are EL1&0 and EL2&0 (the later one
is only available since ARMv8.1).

This fix has to be applied to both versions of the translation tables
library.

Change-Id: If19aaf588551bac7aeb6e9a686cf0c2068e7c181
Signed-off-by: Antonio Nino Diaz <[email protected]>
include/lib/xlat_tables/xlat_tables_defs.h
lib/xlat_tables/xlat_tables_common.c
lib/xlat_tables_v2/xlat_tables_internal.c

index 1c84fe07e9bc52c4862d4eb46ca8d3d6e3a9d81f..5eb1d309d5c6fdcb7d8a8643b314065f3a4bfd46 100644 (file)
  * Permissions bits, and does not define an AP[0] bit.
  *
  * AP[1] is valid only for a stage 1 translation that supports two VA ranges
- * (i.e. in the ARMv8A.0 architecture, that is the S-EL1&0 regime).
- *
- * AP[1] is RES0 for stage 1 translations that support only one VA range
- * (e.g. EL3).
+ * (i.e. in the ARMv8A.0 architecture, that is the S-EL1&0 regime). It is RES1
+ * when stage 1 translations can only support one VA range.
  */
 #define AP2_SHIFT                      U(0x7)
 #define AP2_RO                         U(0x1)
 #define AP1_SHIFT                      U(0x6)
 #define AP1_ACCESS_UNPRIVILEGED                U(0x1)
 #define AP1_NO_ACCESS_UNPRIVILEGED     U(0x0)
+#define AP1_RES1                       U(0x1)
 
 /*
  * The following definitions must all be passed to the LOWER_ATTRS() macro to
 #define AP_RW                          (AP2_RW << 5)
 #define AP_ACCESS_UNPRIVILEGED         (AP1_ACCESS_UNPRIVILEGED    << 4)
 #define AP_NO_ACCESS_UNPRIVILEGED      (AP1_NO_ACCESS_UNPRIVILEGED << 4)
+#define AP_ONE_VA_RANGE_RES1           (AP1_RES1 << 4)
 #define NS                             (U(0x1) << 3)
 #define ATTR_NON_CACHEABLE_INDEX       U(0x2)
 #define ATTR_DEVICE_INDEX              U(0x1)
index 1309936282b8ec824c1b813fb82381bf089efc25..21bf48973975ac0b7b1c6dcc53fc5c237f77b362 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -41,6 +41,7 @@ static unsigned long long xlat_max_pa;
 static uintptr_t xlat_max_va;
 
 static uint64_t execute_never_mask;
+static uint64_t ap1_mask;
 
 /*
  * Array of all memory regions stored in order of ascending base address.
@@ -195,6 +196,7 @@ static uint64_t mmap_desc(mmap_attr_t attr, unsigned long long addr_pa,
        desc |= (attr & MT_NS) ? LOWER_ATTRS(NS) : 0;
        desc |= (attr & MT_RW) ? LOWER_ATTRS(AP_RW) : LOWER_ATTRS(AP_RO);
        desc |= LOWER_ATTRS(ACCESS_FLAG);
+       desc |= ap1_mask;
 
        /*
         * Deduce shareability domain and executability of the memory region
@@ -381,7 +383,17 @@ void init_xlation_table(uintptr_t base_va, uint64_t *table,
                        unsigned int level, uintptr_t *max_va,
                        unsigned long long *max_pa)
 {
-       execute_never_mask = xlat_arch_get_xn_desc(xlat_arch_current_el());
+       int el = xlat_arch_current_el();
+
+       execute_never_mask = xlat_arch_get_xn_desc(el);
+
+       if (el == 3) {
+               ap1_mask = LOWER_ATTRS(AP_ONE_VA_RANGE_RES1);
+       } else {
+               assert(el == 1);
+               ap1_mask = 0;
+       }
+
        init_xlation_table_inner(mmap, base_va, table, level);
        *max_va = xlat_max_va;
        *max_pa = xlat_max_pa;
index aa130646ced7b2c1e0a31b68c9aaf81109a813a9..584d7c4758b430b539a2e822d5f7ee3a6d14f838 100644 (file)
@@ -155,7 +155,7 @@ static uint64_t xlat_desc(const xlat_ctx_t *ctx, uint32_t attr,
                }
        } else {
                assert(ctx->xlat_regime == EL3_REGIME);
-               desc |= LOWER_ATTRS(AP_NO_ACCESS_UNPRIVILEGED);
+               desc |= LOWER_ATTRS(AP_ONE_VA_RANGE_RES1);
        }
 
        /*